package com.recruit.module.message;

import com.recruit.common.CurPool;
import com.recruit.common.util.ApplicationContextUtils;
import com.recruit.common.util.JsonUtils;
import com.recruit.mapper.MsgInfoMapper;
import com.recruit.mapper.SessionListMapper;
import com.recruit.mapper.UserMapper;
import com.recruit.model.MsgInfoDO;
import com.recruit.model.SessionListDO;
import com.recruit.model.UserDO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * down
 */
@Slf4j
@Component
@ServerEndpoint("/websocket/{userId}/{sessionId}")
//此注解相当于设置访问URL
public class WebSocket {

    @Autowired
    private SessionListMapper sessionListMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private MsgInfoMapper msgInfoMapper;

    private Session session;

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "userId") Integer userId,
                       @PathParam(value = "sessionId") String sessionId) {
        this.session = session;
        CurPool.webSockets.put(userId, this);
        List<Object> list = new ArrayList<>();
        list.add(sessionId);
        list.add(session);
        CurPool.sessionPool.put(userId, list);
        System.out.println("【websocket消息】有新的连接，总数为:" + CurPool.webSockets.size());
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        // 断开连接删除用户删除session
        Integer userId = Integer.parseInt(this.session.getRequestParameterMap().get("userId").get(0));
        CurPool.sessionPool.remove(userId);
        CurPool.webSockets.remove(userId);
        if (userMapper == null) {
            this.userMapper = (UserMapper) ApplicationContextUtils.getBeanByBeanId("userMapper");
        }
        UserDO user = userMapper.selectByPrimaryKey(userId);
        CurPool.curUserPool.remove(user.getUsername());
        System.out.println("【websocket消息】连接断开，总数为:" + CurPool.webSockets.size());
    }

    /**
     * 收到客户端消息后调用的方法
     * 后台收到客户端发送过来的消息
     * onMessage 是一个消息的中转站
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message) {

        String sessionId = this.session.getRequestParameterMap().get("sessionId").get(0);
        if (sessionId == null) {
            System.out.println("sessionId 错误");
        }
        // 在这里无法注入Mapper所以使用这种方式注入Mapper
        if (sessionListMapper == null) {
            this.sessionListMapper = (SessionListMapper) ApplicationContextUtils.getBeanByBeanId("sessionListMapper");
        }
        if (userMapper == null) {
            this.userMapper = (UserMapper) ApplicationContextUtils.getBeanByBeanId("userMapper");
        }
        if (msgInfoMapper == null) {
            this.msgInfoMapper = (MsgInfoMapper) ApplicationContextUtils.getBeanByBeanId("msgInfoMapper");
        }
        SessionListDO sessionList = sessionListMapper.selectByPrimaryKey(Integer.parseInt(sessionId));
        UserDO user = userMapper.selectByPrimaryKey(sessionList.getUserId());
        MsgInfoDO msgInfo = new MsgInfoDO();
        msgInfo.setContent(message);
        msgInfo.setCreateTime(new Date());
        msgInfo.setFromUserId(sessionList.getUserId());
        msgInfo.setFromUserName(user.getUsername());
        msgInfo.setToUserId(sessionList.getToUserId());
        msgInfo.setToUserName(sessionList.getListName());
        msgInfo.setUnReadFlag(0);
        // 消息持久化
        msgInfoMapper.insert(msgInfo);

        // 判断用户是否存在，不存在就结束
        List<Object> list = CurPool.sessionPool.get(sessionList.getToUserId());
        if (list == null || list.isEmpty()) {
            // 用户不存在，更新未读数
            sessionListMapper.addUnReadCount(sessionList.getToUserId(), sessionList.getUserId());
        } else {
            // 用户存在，判断会话是否存在
            String id = sessionListMapper.selectIdByUser(sessionList.getToUserId(), sessionList.getUserId()) + "";
            String o = list.get(0) + "";
            if (id.equals(o)) {
                // 会话存在直接发送消息
                sendTextMessage(sessionList.getToUserId(), JsonUtils.objectToJson(msgInfo));
            } else {
                // 判断会话列表是否存在
                if (id == null || "".equals(id) || "null".equals(id)) {
                    // 新增会话列表
                    SessionListDO tmpSessionList = new SessionListDO();
                    tmpSessionList.setUserId(sessionList.getToUserId());
                    tmpSessionList.setToUserId(sessionList.getUserId());
                    tmpSessionList.setListName(user.getUsername());
                    tmpSessionList.setUnReadCount(1);
                    sessionListMapper.insert(tmpSessionList);
                } else {
                    // 更新未读消息数量
                    sessionListMapper.addUnReadCount(sessionList.getToUserId(), sessionList.getUserId());
                }
                // 会话不存在发送列表消息
                List<SessionListDO> sessionLists = sessionListMapper.selectByUserId(sessionList.getToUserId());
                sendTextMessage(sessionList.getToUserId(), JsonUtils.objectToJson(sessionLists));
            }
        }
        System.out.println("【websocket消息】收到客户端消息:" + message);
    }

    @OnError
    public void onError(Session session, Throwable error) {
        log.error("发生错误");
        error.printStackTrace();
    }

    // 此为单点消息 (发送文本)
    public void sendTextMessage(Integer userId, String message) {
        Session session = (Session) CurPool.sessionPool.get(userId).get(1);
        if (session != null) {
            try {
                session.getBasicRemote().sendText(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}
